package main

import (
	"bufio"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/gomodule/redigo/redis"
)

var (
	redisAddress, redisAuth *string
)
var wg sync.WaitGroup

var lock *sync.RWMutex = new(sync.RWMutex)
var f1 *os.File

func WriteLog(str []byte) {
	lock.Lock()
	_, _ = f1.Write(str)
	lock.Unlock()
}

func RedisPool() *redis.Pool {
	return &redis.Pool{
		MaxIdle:     3,                 //最大空闲数
		MaxActive:   20,                //最大活跃数
		IdleTimeout: 240 * time.Second, //最大的空闲连接等待时间，超过此时间后，空闲连接将被关闭
		Dial: func() (redis.Conn, error) {
			//此处对应redis ip及端口号
			conn, err := redis.Dial("tcp", string(*redisAddress))
			if err != nil {
				fmt.Print("连接错误!MSG:%s\n", err.Error())
				return nil, err
			}
			//此处1234对应redis密码
			auth := *redisAuth
			if auth != "" {
				if _, err := conn.Do("AUTH", *redisAuth); err != nil {
					conn.Close()
					fmt.Print("连接密码错误!\n")
					return nil, err
				}
			}

			return conn, err
		},
	}
}

func readVideoResponse(uri string) {
	response, err := http.Get(uri)
	if err != nil {
		WriteLog([]byte(strings.Join([]string{time.Now().Format("2006-01-02 15:04:05"), uri, "请求失败",err.Error()}, "->") + "\n"))
	}else {
		response.Close = true
		defer response.Body.Close()
		WriteLog([]byte(strings.Join([]string{time.Now().Format("2006-01-02 15:04:05"), uri, response.Status}, "->") + "\n"))
	}
	wg.Done()
}

func cacheQueue(redisPool *redis.Pool) {
	conn := redisPool.Get()
	defer conn.Close()
	videourl, _ := redis.String(conn.Do("LPOP", "cdnqueue"))
	if videourl != "" {
		WriteLog([]byte(time.Now().Format("2006-01-02 15:04:05") + "->" + videourl + "\n"))
		response, err := http.Get(videourl)
		if err != nil {
			redis.String(conn.Do("LPUSH", "cdnqueue", videourl))
			WriteLog([]byte(time.Now().Format("2006-01-02 15:04:05") + "->" + "请求失败"+err.Error()+"\n"))
			log.Printf("请求失败")
			return
		}
		response.Close = true
		defer response.Body.Close()
		body, _ := ioutil.ReadAll(response.Body)
		countSplit := strings.Split(videourl, "/")
		uri := strings.Join(countSplit[:len(countSplit)-1], "/")
		scanner := bufio.NewScanner(strings.NewReader(string(body)))
		var readCount = 0
		for scanner.Scan() {
			lineText := scanner.Text()
			if lineText[len(lineText)-2:] == "ts" {
				readCount++
				wg.Add(1)
				os.Remove("data_" + lineText + ".txt")
				go readVideoResponse(uri + "/" + lineText)
			}
		}
		wg.Wait()
		WriteLog([]byte(time.Now().Format("2006-01-02 15:04:05") + "->" + "总共请求:" + strconv.Itoa(readCount) + "个ts文件\n"))
	}

}
//var redisAddress = redisconfig{Address: "127.0.0.1:6379"}
//var redisAuth = redisconfig{Auth: "" }
func main() {
	//fmt.Print(os.Args[1])
	redisAddress = flag.String("host", "127.0.0.1:6379", "redis链接地址")
	redisAuth = flag.String("auth", "", "redis链接密码")
	ts := flag.Int("ts", 5, "延迟时间")
	flag.Parse()

	redisPool := RedisPool()
	defer RedisPool().Close()
	var err error
	f1, err  = os.OpenFile("m3u8.log", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0600)
	if err != nil {
		fmt.Println("打开文件失败:"+err.Error())
		return
	}
	defer f1.Close()
	for {
		cacheQueue(redisPool)
		fmt.Print("-------------------\n")
		time.Sleep(time.Duration(*ts) * time.Second)
	}

}
